<script setup lang="ts">
import { computed, nextTick, ref, watch } from "vue";
import InsertBtn from "./InsertBtn.vue";
import { createNodeTask } from "../../ProcessNodes";
import type { FlowModelNode } from "../../ProcessDef";

const props = defineProps({
  headerColor: { type: String, default: "#EC8151" }, //头部颜色
  flowHistory: Array,
  headerIcon: String, //头部图标
  type: String, //节点类型
  content: String, //节点内容
  readonly: Boolean, //是否禁用，不可编辑
  end: Boolean,
  index: Number,
  showError: Boolean, //是否显示错误状态
  errorInfo: String, //错误信息
  onlyJob: {
    type: Boolean,
    default: false
  },
  showClose: {
    type: Boolean,
    default: true
  },
  showBody: {
    type: Boolean,
    default: true
  },
  placeholder: {
    type: String,
    default: "请设置"
  }
});

const enableEdit = ref(false);
const nodeNameInput = ref();
const emit = defineEmits(["delete", "select", "insertNode"]);
const _value = defineModel<FlowModelNode>();

const getHeaderColor = computed(() => {
  if (!props.flowHistory || props.flowHistory.length === 0) {
    return props.headerColor;
  }
  const finishs = props.flowHistory.filter(item => {
    return item.nodeCode === _value.value.code && item.status === "1";
  });
  const running = props.flowHistory.filter(item => {
    return item.nodeCode === _value.value.code && item.status === "0";
  });
  if (finishs && finishs.length > 0) {
    return "green";
  }
  if (running && running.length > 0) {
    return "blue";
  }
  return props.headerColor;
});

const insertTask = () => {
  if (!_value.value.props.tasks) {
    _value.value.props.tasks = [];
  }
  _value.value.props.tasks.push(createNodeTask(_value.value.props.tasks.length + 1));
};

const taskContent = task => {
  let name = "没有设置办理人";
  if (task.jobType === "0") {
    if (task.userList && task.userList.length > 0) {
      const userNames = task.userList
        .map(item => {
          return item.text;
        })
        .join(",");
      name = `用户[${userNames}]审批`;
    }
  } else if (task.jobType === "1") {
    if (task.roleList && task.roleList.length > 0) {
      const userNames = task.roleList
        .map(item => {
          return item.text;
        })
        .join(",");
      name = `角色[${userNames}]审批`;
    }
  } else if (task.jobType === "3") {
    name = "[发起人]审批";
  } else if (task.jobType === "4") {
    if (task.dynamicUserType === "0") {
      name = `[发起人]第${task.dynamicUserLeaderLevel}级主管审批`;
    } else {
      name = `${task.dynamicUserName}第${task.dynamicUserLeaderLevel}级主管审批`;
    }
  } else if (task.jobType === "5") {
    if (task.dynamicUserType === "0") {
      name = `[发起人]连续${task.dynamicUserLeaderLevel}级主管`;
    } else {
      name = `[${task.dynamicUserName}]连续${task.dynamicUserLeaderLevel}级主管审批`;
    }
  } else if (task.jobType === "6") {
    name = `部门[${task.dynamicDeptName}]主管审批`;
  } else if (task.jobType === "7") {
    name = `动态办理人[${task.dynamicUserKey}]审批`;
  } else {
    name = "没有设置办理人";
  }
  return name;
};

const deleteTask = index => {
  _value.value.props.tasks.splice(index, 1);
};

watch(enableEdit, () => {
  if (enableEdit.value) {
    nextTick(() => {
      nodeNameInput.value.focus();
    });
  }
});
</script>

<template>
  <div class="w-p-node">
    <el-tooltip
      v-if="showError"
      effect="dark"
      :content="errorInfo || '设置错误'"
      placement="top-start"
    >
      <el-icon size="20" class="w-node-err-tip">
        <WarningFilled />
      </el-icon>
    </el-tooltip>
    <div
      :class="{ 'w-p-node-body': true, 'w-node-err': showError }"
      v-if="showBody"
      :style="{ '---shadowColor': headerColor }"
    >
      <div class="node-header-container" :style="{ 'background-color': getHeaderColor }">
        <div>
          <el-icon size="15" v-if="!enableEdit">
            <component :is="headerIcon" />
          </el-icon>
          <el-input
            ref="nodeNameInput"
            v-if="enableEdit"
            @blur="enableEdit = false"
            size="small"
            v-model="_value.name"
          />
          <div
            class="w-row-text"
            v-else
            @click="
              () => {
                if (!readonly) enableEdit = true;
              }
            "
          >
            {{ _value.name }}
          </div>
        </div>
        <el-icon class="w-node-del" size="16" v-if="showClose && !readonly" @click="emit('delete')">
          <Close />
        </el-icon>
      </div>
      <div class="node-content-container" @click="emit('select')">
        <div class="other-content-row" v-if="type !== 'Job'">
          <el-text line-clamp="4">{{ content || placeholder }}</el-text>
          <el-icon v-if="!readonly" size="20" @click="emit('select')">
            <ArrowRight />
          </el-icon>
        </div>
        <div
          class="job-content-row"
          v-else
          v-for="(item, taskIndex) in _value.props.tasks"
          :key="item.id"
          @click.stop="emit('select', taskIndex)"
        >
          <el-text>{{ item.name }}</el-text>
          <el-tooltip placement="right" :content="taskContent(item)">
            <el-icon size="28">
              <UserFilled />
            </el-icon>
          </el-tooltip>
          <el-icon
            size="28"
            @click.stop="deleteTask(taskIndex)"
            v-if="taskIndex !== 0 && !readonly"
          >
            <CloseBold />
          </el-icon>
          <el-icon size="28">
            <ArrowRight />
          </el-icon>
        </div>
      </div>
      <div
        class="node-bottom-container"
        v-if="type === 'Job' && !props.readonly"
        @click.stop="insertTask"
      >
        <el-icon size="20">
          <Plus />
        </el-icon>
      </div>
    </div>
    <div class="w-p-node-add" v-if="!end">
      <insert-btn
        v-if="!readonly"
        :only-job="props.onlyJob"
        @insertNode="type => emit('insertNode', type)"
      />
    </div>
  </div>
</template>

<style scoped lang="scss">
.w-p-node {
  position: relative;
  width: $node-width;
  margin-bottom: 8px;

  .w-node-err-tip {
    position: absolute;
    right: -30px;
    color: var(--el-color-danger);
  }

  .w-p-node-body {
    overflow: hidden;
    cursor: pointer;
    background: white;
    border-radius: 5px;
    box-shadow: 0 0 5px 0 #d8d8d8;

    .node-header-container {
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 25px;
      padding: 0 10px;
      font-size: 13px;
      color: white;

      .w-row-text {
        &:hover {
          text-decoration: underline;
        }
      }

      .w-node-del {
        display: none;
      }

      & > div {
        display: flex;
        align-items: center;

        & > div {
          width: calc($node-width - 50px);
          margin-left: 3px;
        }
      }

      input {
        width: calc($node-width - 50px);
        border: none;
        border-radius: 5px;

        &:focus {
          outline: none;
        }
      }
    }

    .node-content-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      min-height: 50px;
      padding: 5px 5px 5px 15px;
      font-size: 15px;
      color: #656363;

      .other-content-row {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        width: 92%;
        line-height: 30px;
        word-wrap: break-word;
      }

      .job-content-row {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        width: 92%;
        line-height: 30px;
        word-wrap: break-word;

        :first-child {
          width: 60%;
        }
      }
    }

    .node-bottom-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      min-height: 20px;
    }

    &:hover {
      box-shadow: 0 0 5px 0 var(---shadowColor);

      .w-node-del {
        display: inline;
      }
    }
  }

  .w-p-node-add {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: $node-line-len;

    &:before {
      position: absolute;
      width: $node-line-width;
      height: $node-line-len;
      content: "";
      background: $node-line-color;
    }

    &:after {
      position: absolute;
      top: $node-line-len;
      left: 50%;
      width: 0;
      content: "";
      border-color: $node-line-color transparent transparent;
      border-style: solid;
      border-width: 8px 6px 4px;
      transform: translateX(-50%);
    }
  }
}
</style>
